﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using Cesave.DistributedServices.PermisosModule.WindowsHost.Resources;
using Cesave.Domain.Core.Entities;
using Cesave.Domain.PermisosModule.Contracts.Ciclos;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.CrossCutting.IoC;

namespace Cesave.DistributedServices.PermisosModule.WindowsHost.ViewModels.Catalogs.Ciclos
{
	public partial class CiclosViewModel
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private List<Ciclo> _ciclos;

		/// <summary>
		/// 
		/// </summary>
		private Ciclo _ciclo;

		#endregion

		#region Public properties

		/// <summary>
		/// 
		/// </summary>
		public List<Ciclo> Ciclos
		{
			get
			{
				return _ciclos;
			}
			private set
			{
				_ciclos = value;
				if (_ciclos != null)
					RaisePropertyChanged("Ciclos");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public Ciclo Ciclo
		{
			get
			{
				return _ciclo;
			}
			private set
			{
				_ciclo = value;
				if (_ciclo != null)
					RaisePropertyChanged("Ciclo");
			}
		}

		#endregion

		#region Actions

		/// <summary>
		/// 
		/// </summary>
		private void LoadCiclos()
		{
			StartWaiting();
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (sender, e) =>
				{
					ICicloService cicloService = IoCFactory.Resolve<ICicloService>();
					e.Result = cicloService.FindAllCiclos();
				};
				worker.RunWorkerCompleted += (sender, e) =>
				{
					EndWaiting();
					if (!e.Cancelled && e.Error == null)
						Ciclos = e.Result as List<Ciclo>;
					else if (e.Error != null)
						MessageBox.Show(
							_ciclosView,
							e.Error.Message,
							WindowTitles.CiclosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SaveCiclo(object s, EventArgs args)
		{
			if (_ciclosView.validator.Validate().IsValid)
			{
				StartWaiting();
				using (BackgroundWorker worker = new BackgroundWorker())
				{
					worker.DoWork += (sender, e) =>
					{
						ICicloService cicloService = IoCFactory.Resolve<ICicloService>();
						if (Ciclo.ChangeTracker.State == ObjectState.Added)
							cicloService.AddCiclo(Ciclo);
						else if (Ciclo.ChangeTracker.State == ObjectState.Modified)
							cicloService.ChangeCiclo(Ciclo);
						Ciclo.AcceptChanges();
					};
					worker.RunWorkerCompleted += (sender, e) =>
					{
						EndWaiting();
						if (!e.Cancelled && e.Error == null)
							LoadCiclos();
						else if (e.Error != null)
							MessageBox.Show(
								_ciclosView,
								e.Error.Message,
								WindowTitles.CiclosWindowTitle,
								MessageBoxButtons.OK,
								MessageBoxIcon.Error
							);
					};
					worker.WorkerSupportsCancellation = true;
					worker.RunWorkerAsync();
				}
			}
		}	

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void AddNewCiclo(object sender, EventArgs e)
		{
			_ciclosView.cicloBindingSource.AddingNew += AddingNewCiclo;
			_ciclosView.cicloBindingSource.AddNew();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void AddingNewCiclo(object sender, AddingNewEventArgs e)
		{
			Ciclo ciclo = new Ciclo
			{
				Actual = false,
				CicloGuid = Guid.NewGuid(),
				CicloId = 0,
				Nombre = string.Empty,
				Status = true,
			};
			Ciclo = ciclo;
			Ciclo.MarkAsAdded();
			e.NewObject = Ciclo;
			FocusDefaultControl();
		}

		/// <summary>
		/// 
		/// </summary>
		private void DeleteCiclo(object s, EventArgs args)
		{
			StartWaiting();
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (sender, e) =>
				{
					ICicloService cicloService = IoCFactory.Resolve<ICicloService>();
					Ciclo.MarkAsDeleted();
					cicloService.DeleteCiclo(Ciclo);
					Ciclo.AcceptChanges();
				};
				worker.RunWorkerCompleted += (sender, e) =>
				{
					EndWaiting();
					if (!e.Cancelled && e.Error == null)
						LoadCiclos();
					else if (e.Error != null)
						MessageBox.Show(
							_ciclosView,
							e.Error.Message,
							WindowTitles.CiclosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void MakeCicloActual(object s, EventArgs args)
		{
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (sender, e) =>
				{
					ICicloService cicloService = IoCFactory.Resolve<ICicloService>();
					cicloService.MakeCicloActual(Ciclo);
				};
				worker.RunWorkerCompleted += (sender, e) =>
				{
					if (!e.Cancelled && e.Error == null)
						LoadCiclos();
					else
						MessageBox.Show(
							_ciclosView,
							e.Error.Message,
							WindowTitles.CiclosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		#endregion

		#region Event methods

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SetCurrentCiclo(object sender, EventArgs e)
		{
			BindingSource bindingSource = sender as BindingSource;
			if (bindingSource != null)
				if (bindingSource.Current != null)
					Ciclo = bindingSource.Current as Ciclo;
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnCiclosPropertyChanged()
		{
			_ciclosView.cicloBindingSource.DataSource = Ciclos;
			_ciclosView.cicloBindingSource.CurrentChanged += SetCurrentCiclo;
			SetCurrentCiclo(_ciclosView.cicloBindingSource, new EventArgs());
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnCicloPropertyChanged()
		{
			Ciclo.MarkAsModified();
		}

		#endregion

	}
}
